/*
 * Session.cpp
 *
 *  Created on: 2009-3-18
 *      Author: P.Weiwen
 * Description: 应用网关上用来转发数据的会话通道，连接两个socket。
 *
 */

#include "Session.h"
#include "XPacket.h"

u_short Session::m_count = 0;

Session::Session():m_serv_socket(NULL){
//	m_cli_socket.SetReadHandler(this);
	m_sn = m_count++;
}

int Session::OnRead(Epoller &sender,EpollEventArg &e){
	debug("Session::OnRead==>\n");
	byte buf[MAX_READ_BUF];
	int flg = ReadBlock(buf,MAX_READ_BUF);
	XPacket xp;
	if(flg>0){
		char *p = xp.alloc_buf(flg,0,0);
		if(!p){
			debug("can not allocate a packet!\n");
			return -err_outmemory;
		}
		memcpy(xp.data_begin(),buf,flg);
		return OnRecvCli(xp);
	}else if(flg == 0){
		debug("Session[%d] closed by peer==>!\n",flg);
		sender.UnRegisterHandler(*this,READ_EVENT|WRITE_EVENT);
		Close();
	}else{
		debug("recv error:%d\n",flg);
	}
	return flg;
}
int Session::OnWrite(Epoller &sender,EpollEventArg &e){
	debug("Session::OnWrite --->\n");

	return Send();
}
int Session::Send() {
	int flg = 0;
	while (!m_down_queue.empty()) {
		debug("queue len:%d\n",m_down_queue.size());
		XPacket &xp = m_down_queue.front();
		debug("count:%d\n",m_down_queue.size());
		flg = WriteBlock(xp.data_begin(), xp.data_size());
		if (flg < 0) {
			debug("error:%d\n",flg);
			return flg;
		} else if (flg < xp.data_size()) {
			xp.set_head(xp.get_head() + flg);
			break;
		} else { //发完一个完整的包
			m_down_queue.pop();
		}
	}
}

int Session::OnRecvCli(XPacket& xp){
//在这里添加你的代码

	return SendToSrv(xp);
}
int Session::OnRecvSrv(XPacket& xp){
	//在这里添加你的代码

	return SendToCli(xp);
}
int Session::SendToCli(XPacket& xp){
	m_down_queue.push(xp);

	return Send();
}
int Session::SendToSrv(XPacket & xp){
	m_up_queue.push(xp);
	return m_serv_socket->Send();
}

Session::~Session() {
	// TODO Auto-generated destructor stub
}
